#ifndef STREAM_H
#define STREAM_H

// The following is the new and improved stream class (it's been converted
// to C++ if you're wondering).  The older stream class follows this class.
//
// NOTE: If you are creating a new class which uses streams, please use the
//       new C++ version as the old C version has been deprecated.
//

namespace Library
{

/**
 * An abstract base class which defines a stream interface.
 */
class PLIBEXP Stream
{
	public:
		enum Error		{ eof = -1 };
		enum SeekFrom	{ beginning, current, end };
//		enum AccessMode	{ readable, writable, executable, exists };

						Stream();
		virtual			~Stream();

		// binary
		virtual int32	read(void * buffer, int32 length) = 0;
		virtual int32	write(void * buffer, int32 length) = 0;
		virtual int32	seek(int32 offset, SeekFrom from) = 0;
		virtual int32	tell() = 0;

		// text
		virtual char *	readString(char * buffer, int32 length);
		virtual char	readCharacter();
		virtual char *	writeString(char * string);
		virtual char	writeCharacter(char c);

		virtual uint16*	readString(uint16* buffer, int32 length);
		virtual uint16	readCharacter16();
		virtual uint16*	writeString(uint16* string);
		virtual uint16	writeCharacter(uint16 c);

	// prohibited
	private:
		Stream(Stream &);
		Stream & operator=(Stream &);
};


//----------------------------------------------------------------------------
// Documentation, prohibited methods (unimplemented)
//

/**
 * @fn Library::Stream::Stream(Stream &)
 *
 * This method is reserved and unimplemented.  It has been defined for
 * Orthodox Canonical Form (OCF) compliance to prevent shallow object copies
 * from inadvertent use.
 */

/**
 * @fn Library::Stream & Library::Stream::operator=(Stream &)
 *
 * This method is reserved and unimplemented.  It has been defined for
 * Orthodox Canonical Form (OCF) compliance to prevent shallow object copies
 * from inadvertent use.
 */

}; // namespace Library


// This is the older stream class implemented for C.  This code will soon
// be obsolete, so all new code should use the C++ class defined above.
#include "pstream.h"


#define streamEOF		(-1)

// specifing 0 for mode means read/write with file being created
//
#define streamO_RDONLY	(1L << 0)
#define streamO_WRONLY	(1L << 1)	// bit 2 is reserved.
#define streamO_APPEND	(1L << 3)
#define streamO_TEXT	(1L << 4)
#define streamO_UPDATE  (1L << 5)   // read/write access to existing file

#define streamSEEK_SET	(1L)
#define streamSEEK_CUR	(2L)
#define streamSEEK_END	(3L)

#define streamR_OK		(1L << 0)
#define streamW_OK		(1L << 1)
#define streamX_OK		(1L << 2)
#define streamF_OK		(1L << 3)


typedef struct _CStream
{
	_DEP_STREAM
	uint32		cMode;

#ifdef DEBUG_CSTREAM
	char *		cFilename;
#endif
} CStream;


// public COMMON interfaces
PLIBEXP pCStream	newCStream(const String & Filename, uint32 Mode);
PLIBEXP void 		deleteCStream(pCStream This);

// BINARY routines.
PLIBEXP int32	CStreamRead(pCStream This, void *Buffer, uint32 Length);
PLIBEXP int32	CStreamSeek(pCStream This, int32 Offset, uint32 Where);
PLIBEXP int32	CStreamTell(pCStream This);
PLIBEXP bool8	CStreamTruncate(pCStream, uint32 newSize);	// or expands

// TEXT routines.
PLIBEXP char *	CStreamGetString(pCStream This, void *Buffer, uint32 Length);
PLIBEXP char	CStreamGetChar(pCStream This);

// MISC routines... (not implemented!!!)
PLIBEXP int32	CStreamAccess(const String & Filename, uint32 Mode);
PLIBEXP bool8	CStreamCreateDir(const String & Path);
PLIBEXP bool8	CStreamDelFile(const String & Filename);
PLIBEXP void	CStreamGetDosDateTime(pCStream,
					uint16* lastModDate, uint16* lastModTime);
PLIBEXP int32	CStreamGetMaxFilePath();

#ifndef CSTREAM_READONLY_FILESYSTEM
	// BINARY routines.
	PLIBEXP int32	CStreamWrite(pCStream This, void *Buffer, uint32 Length);

	// TEXT routines.
	PLIBEXP char *	CStreamPutString(pCStream This, void *Buffer);
	PLIBEXP char	CStreamPutChar(pCStream This, char Char);
#else
	// BINARY routines.
	#define			CStreamWrite(x,y,z)		(streamEOF)

	// TEXT routines.
	#define			CStreamPutString(y,z)	(NULL)
	#define			CStreamPutChar(y,z)		(streamEOF)
#endif

#endif
